package cn.sxgan.gen.services.core;// CodeGenerator.java

import cn.sxgan.gen.enums.DataSourceType;
import cn.sxgan.gen.enums.DatePatternEnum;
import cn.sxgan.gen.model.ColumnInfo;
import cn.sxgan.gen.model.DbTable;
import cn.sxgan.gen.services.base.DataSourceQuery;
import cn.sxgan.gen.services.base.DataSourceQueryFactory;
import cn.sxgan.gen.utils.DateUtils;
import cn.sxgan.gen.utils.JdbcTypeConverterUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class CodeGeneratorService {
    
    @Autowired
    DataSourceQueryFactory dataSourceQueryFactory;

    @Autowired
    private Configuration freemarkerConfig;
    
    @Value("${generator.output-dir}")
    private String outputDir;
    
    // 主生成方法
    public void generate(String tableName) throws Exception {
        Map<String, Object> data = prepareTemplateData(tableName);
        
        // 创建输出目录
        new File(outputDir).mkdirs();
        
        // 生成Model
        generateFile("entity.ftl",
                    data, 
                    outputDir + "/model/" + data.get("className") + ".java");
        // 生成VO
        generateFile("vo.ftl",
                data,
                outputDir + "/model/vo/" + data.get("className") + ".java");
        // 生成query
        generateFile("query.ftl",
                data,
                outputDir + "/model/query/" + data.get("className") + ".java");
        // 生成convert
        generateFile("convert.ftl",
                data,
                outputDir + "/model/convert/" + data.get("className") + ".java");
        
        // 生成Mapper
        generateFile("mapper.ftl", 
                    data, 
                    outputDir + "/mapper/" + data.get("className") + "Mapper.java");
        
        // 生成MapperXML
        generateFile("mapperxml.ftl", 
                    data, 
                    outputDir + "/mapper/xml/" + data.get("className") + "Mapper.xml");
        
        // 生成Service
        generateFile("service.ftl", 
                    data, 
                    outputDir + "/service/" + data.get("className") + "Service.java");
        
        // 生成ServiceImpl
        generateFile("serviceImpl.ftl", 
                    data, 
                    outputDir + "/service/impl/" + data.get("className") + "ServiceImpl.java");
    }
    
    private void generateFile(String templateName, 
                             Map<String, Object> data, 
                             String outputPath) throws Exception {
        Template template = freemarkerConfig.getTemplate(templateName);
        File file = new File(outputPath);
        new File(file.getParent()).mkdirs();
        file.createNewFile();
        try (Writer out = new FileWriter(outputPath)) {
            template.process(data, out);
            System.out.println("生成成功: " + outputPath);
        }
    }
    
    // 准备模板数据（实际项目中需连接数据库获取表结构）
    private Map<String, Object> prepareTemplateData(String tableName) {
        Map<String, Object> data = new HashMap<>();
        try {
            // 表名转类名（下划线转驼峰）
            String className = convertToCamelCase(tableName, true);
            String varName = convertToCamelCase(tableName, false);
            DataSourceQuery dataSourceQuery = dataSourceQueryFactory.getDataSourceQuery(DataSourceType.MySQL);
            List<DbTable> dbTables = dataSourceQuery.selectDbTables(tableName);
            DbTable tableInfo = dbTables.getFirst();
            List<ColumnInfo> tableColumns = dataSourceQuery.getTableColumns(tableName);
            // 模拟表字段（实际应从数据库读取）
            List<Map<String, String>> columns = new ArrayList<>();
            for (ColumnInfo tableColumn : tableColumns) {
                Map<String, String> columnInfo = columnInfo(tableColumn.getName(), tableColumn.getType(), tableColumn.getComment());
                columns.add(columnInfo);
            }
            
            data.put("tableName", tableName);
            data.put("tableComment", tableInfo.getTableComment());
            data.put("className", className);
            data.put("varName", varName);
            data.put("columns", columns);
            data.put("package", "com.example");
            // 时间
            String dateTimeStr = DateUtils.getTimeString(DatePatternEnum.YYYY_MM_DD_HH_MM_SS);
            data.put("author", "sxgan");
            data.put("dateTime", dateTimeStr);
            data.put("version", "1.0.0");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("异常", e);
            
        }
        return data;
    }
    
    
    
    private Map<String, String> columnInfo(String name, String type, String comment) {
        Map<String, String> col = new HashMap<>();
        col.put("column", name);
        col.put("type", type.toUpperCase());
        col.put("javaType", JdbcTypeConverterUtils.convertToJavaType(type));
        col.put("property", convertToCamelCase(name, false));
        col.put("comment", comment);
        return col;
    }
    
    private String convertToCamelCase(String input, boolean capitalFirst) {
        StringBuilder result = new StringBuilder();
        for (String word : input.split("_")) {
            if (word.isEmpty()) continue;
            if (result.length() == 0 && !capitalFirst) {
                result.append(word.toLowerCase());
            } else {
                result.append(word.substring(0, 1).toUpperCase());
                result.append(word.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }
}